package com.distribute.sso.service.impl;

import java.util.Date;
import java.util.List;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.omg.PortableInterceptor.USER_EXCEPTION;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import com.distribute.common.pojo.DistributeResult;
import com.distribute.common.util.CookieUtils;
import com.distribute.common.util.JsonUtils;
import com.distribute.mapper.DbUserMapper;
import com.distribute.pojo.DbUser;
import com.distribute.pojo.DbUserExample;
import com.distribute.pojo.DbUserExample.Criteria;
import com.distribute.sso.dao.JedisClient;
import com.distribute.sso.service.UserService;

/**这是非正统的sso。。。。。，更好的sso是区分全局会话和局部会话的。sso主要是依靠cookie（path域的功能）
 * 流程：各个系统向SSO系统发出登录请求或者验证用户是否登录，若是登录请求，SSO系统判断相应的验证信息通过后，利用UUID生成一个随机token，并以该token为key，value为用户信息（去除密码）
 * 存入redis中，最后将token通过cookie返回给客户端系统。客户端系统访问受限资源的时候，首先检查是否存在token cookie，不存在则跳转到登录，存在则验证token是否合法或过期。
 * 用户管理Service
 * <p>
 * Title: UserServiceImpl
 * </p>
 * <p>
 * Description:
 * </p>
 * <p>
 * Company: www.mings.com
 * </p>
 * 
 * @author 曾晓明
 * @date 2018年01月14日上午10:28:39
 * @version 1.0
 */
@Service
public class UserServiceImpl implements UserService {

	@Autowired
	private DbUserMapper userMapper;

	@Autowired
	private JedisClient jedisClient;

	@Value("${REDIS_USER_SESSION_KEY}")
	private String REDIS_USER_SESSION_KEY;
	@Value("${SSO_SESSION_EXPIRE}")
	private Integer SSO_SESSION_EXPIRE;

	@Override
	public DistributeResult checkData(String content, Integer type) {
		// 创建查询条件
		DbUserExample example = new DbUserExample();
		Criteria criteria = example.createCriteria();
		// 对数据进行校验：1、2、3分别代表username、phone、email
		// 用户名校验
		if (1 == type) {
			criteria.andUsernameEqualTo(content);
			// 电话校验
		} /*else if (2 == type) {
			criteria.andPhoneEqualTo(content);
			// email校验
		} else {
			criteria.andEmailEqualTo(content);
		}*/
		// 执行查询
		List<DbUser> list = userMapper.selectByExample(example);
		if (list == null || list.size() == 0) {
			return DistributeResult.ok(true);
		}
		return DistributeResult.ok(false);
	}

	@Override
	public DistributeResult createUser(DbUser user) {
		user.setUpdated(new Date());
		user.setCreated(new Date());
		// md5加密
		user.setPassword(DigestUtils.md5DigestAsHex(user.getPassword().getBytes()));
		userMapper.insert(user);
		return DistributeResult.ok();
	}

	/**
	 * 用户登录
	 * <p>
	 * Title: userLogin
	 * </p>
	 * <p>
	 * Description:
	 * </p>
	 * 
	 * @param username
	 * @param password
	 * @return
	 */
	@Override
	public DistributeResult userLogin(String username, String password, HttpServletRequest request,
			HttpServletResponse response) {

		DbUserExample example = new DbUserExample();
		Criteria criteria = example.createCriteria();
		criteria.andUsernameEqualTo(username);
		List<DbUser> list = userMapper.selectByExample(example);
		// 如果没有此用户名
		if (null == list || list.size() == 0) {
			return DistributeResult.build(400, "用户名或密码错误");
		}
		DbUser user = list.get(0);
		// 比对密码
		if (!DigestUtils.md5DigestAsHex(password.getBytes()).equals(user.getPassword())) {
			return DistributeResult.build(400, "用户名或密码错误");
		}
		// 生成token
		String token = UUID.randomUUID().toString();
		// 保存用户之前，把用户对象中的密码清空。
		user.setPassword(null);
		// 把用户信息写入redis
		jedisClient.set(REDIS_USER_SESSION_KEY + ":" + token, JsonUtils.objectToJson(user));
		// 设置session的过期时间，到时间该key被删除
		jedisClient.expire(REDIS_USER_SESSION_KEY + ":" + token, SSO_SESSION_EXPIRE);

		// 添加写cookie的逻辑，cookie的有效期是关闭浏览器就失效。
		CookieUtils.setCookie(request, response, "TT_TOKEN", token);

		// 返回token
		return DistributeResult.ok(token);
	}

	@Override
	public DistributeResult getUserByToken(String token) {

		// 根据token从redis中查询用户信息
		String json = jedisClient.get(REDIS_USER_SESSION_KEY + ":" + token);
		System.out.println(json+"jjjjjjjjjjjjjjjjjjjjjj");
		// 判断是否为空
		if (StringUtils.isBlank(json)) {
			return DistributeResult.build(400, "此session已经过期，请重新登录");
		}
		// 更新过期时间
		jedisClient.expire(REDIS_USER_SESSION_KEY + ":" + token, SSO_SESSION_EXPIRE);
		// 返回用户信息
		return DistributeResult.ok(JsonUtils.jsonToPojo(json, DbUser.class));
	}

	@Override
	public DistributeResult userLogout(String token) {
		jedisClient.del(REDIS_USER_SESSION_KEY + ":" + token);
		return DistributeResult.ok();
	}

	@Override
	public DistributeResult updateUserPass(String userName, String password,String token) {
		DbUserExample example = new DbUserExample();
		Criteria citeria = example.createCriteria();
		citeria.andUsernameEqualTo(userName); 
		List<DbUser> list = userMapper.selectByExample(example);
		if (list != null && list.size() > 0) {
			DbUser user = list.get(0);
			// md5加密
			user.setPassword(DigestUtils.md5DigestAsHex(password.getBytes()));
			user.setUpdated(new Date());
			userMapper.updateByPrimaryKey(user);
			// 把用户信息写入redis
			jedisClient.set(REDIS_USER_SESSION_KEY + ":" + token, JsonUtils.objectToJson(user));
			return DistributeResult.ok();
		}else {
			return DistributeResult.build(500, "ERROR");
		}
		
	}

	@Override
	public DistributeResult updateUserInfo(String userName, String phone, String email,String token) {
		DbUserExample example = new DbUserExample();
		Criteria citeria = example.createCriteria();
		citeria.andUsernameEqualTo(userName); 
		List<DbUser> list = userMapper.selectByExample(example);
		if (list != null && list.size() > 0) {
			DbUser user = list.get(0);
			// md5加密
			user.setPhone(phone);
			user.setEmail(email);
			user.setUpdated(new Date());
			userMapper.updateByPrimaryKey(user);
			// 把用户信息写入redis
			jedisClient.set(REDIS_USER_SESSION_KEY + ":" + token, JsonUtils.objectToJson(user));
			return DistributeResult.ok();
		}else {
			return DistributeResult.build(500, "ERROR");
		}
	}

	@Override
	public boolean checkUserPass(String userName, String password) {
		DbUserExample example = new DbUserExample();
		Criteria citeria = example.createCriteria();
		citeria.andUsernameEqualTo(userName); 
		List<DbUser> list = userMapper.selectByExample(example);
		if (list != null && list.size() > 0) {
			DbUser user = list.get(0);
			// md5加密
			boolean flag = user.getPassword().equals((DigestUtils.md5DigestAsHex(password.getBytes())));
			return flag;
			
		}else {
			return false;
		}
	}

}
